package net.bplaced.streetfighter.lib.async.task;

import net.bplaced.streetfighter.lib.utils.CallBack;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;

/**
 * Provides an abstract class to perform asynchronous tasks.
 * 
 * @author Sebastian Hoffmann <bo.hoffi@googlemail.com>
 */
public abstract class AbstractLoaderTask<Params, ResultType>
        extends AsyncTask<Params, Void, ResultType> {

    private ProgressDialog progressDialog;
    private final Context context;
    private final String progessMessage;
    private final CallBack<ResultType> onFinished;

    /**
     * Constructs a AbstractLoaderTask.
     * 
     * @param context
     *            Context used for the progress dialog.
     * @param progressMessage
     *            Message which should be displayed on the dialog.
     * @param onFinished
     *            Callback to be invoked after the task has completed.
     */
    public AbstractLoaderTask(Context context, String progressMessage, CallBack<ResultType> onFinished) {

        this.context = context;
        this.progessMessage = progressMessage;
        this.onFinished = onFinished;
    }

    @Override
    protected ResultType doInBackground(Params... params) {

        return this.performInBackground(params);
    }

    @Override
    protected void onPostExecute(ResultType result) {

        this.onFinished.callbackAction(result);
        this.progressDialog.dismiss();
    }

    /**
     * Displays a progress dialog with a given message.
     */
    @Override
    protected void onPreExecute() {

        this.progressDialog = new ProgressDialog(this.context);
        this.progressDialog.setMessage(this.progessMessage);
        this.progressDialog.setIndeterminate(true);
        this.progressDialog.setCancelable(false);
        this.progressDialog.show();
    }

    /**
     * Performs a task in background.
     * 
     * @param params
     *            Array of parameters for the background task.
     * @return Instance of the defined result type.
     */
    abstract ResultType performInBackground(Params... params);
}